﻿using OpenTK.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LDLib
{
    /// <summary>
    /// Static class for input information.
    /// Holds information about keyboard and mouse state.
    /// 
    /// To find out if i.e. the space bar was pressed, you can
    /// call: Input.IsKeyDown(Key.Space)
    /// </summary>
    public static class Input
    {
        /// <summary>
        /// Set of keys that were pressed down this frame
        /// </summary>
        internal static HashSet<Key> keysDown = new HashSet<Key>();

        /// <summary>
        /// Set of keys that were lifted up this frame 
        /// </summary>
        internal static HashSet<Key> keysUp = new HashSet<Key>();

        /// <summary>
        /// Set of keys that were held down this frame
        /// </summary>
        internal static HashSet<Key> keysPressed = new HashSet<Key>();

        /// <summary>
        /// Set of mouse buttons that were pressed down this frame
        /// </summary>
        internal static HashSet<MouseButton> mouseDown = new HashSet<MouseButton>();

        /// <summary>
        /// Set of mouse buttons that were lifted up this frame
        /// </summary>
        internal static HashSet<MouseButton> mouseUp = new HashSet<MouseButton>();

        /// <summary>
        /// Set of mouse buttons that were held down this frame
        /// </summary>
        internal static HashSet<MouseButton> mousePressed = new HashSet<MouseButton>();

        /// <summary>
        /// Mouse X screen coordinate during the previous frame
        /// </summary>
        internal static int mouseLastFrameX = 0;

        /// <summary>
        /// Mouse Y screen coordinate during the previous frame
        /// </summary>
        internal static int mouseLastFrameY = 0;

        /// <summary>
        /// Mouse X screen coordinate during the current frame
        /// </summary>
        internal static int mouseX = 0;

        /// <summary>
        /// Mouse X screen coordinate during the current frame
        /// </summary>
        public static int MouseX { get { return mouseX; } }

        /// <summary>
        /// Mouse Y screen coordinate during the current frame
        /// </summary>
        internal static int mouseY = 0;

        /// <summary>
        /// Mouse Y screen coordinate during the current frame
        /// </summary>
        public static int MouseY { get { return mouseY; } }

        /// <summary>
        /// Mouse delta X (the amount the mouse moved since the previous frame)
        /// </summary>
        internal static int mouseDeltaX = 0;

        /// <summary>
        /// Mouse delta Y (the amount the mouse moved since the previous frame)
        /// </summary>
        internal static int mouseDeltaY = 0;

        /// <summary>
        /// Indicator whether the mouse moved since the last frame or not
        /// </summary>
        internal static bool mouseMoved = false;

        /// <summary>
        /// Checks if the given key was pressed down.
        /// This returns true only for a single frame.
        /// </summary>
        /// <param name="key">Key to check</param>
        /// <returns>True if the key was pressed down, false otherwise</returns>
        public static bool IsKeyDown(Key key)
        {
            return keysDown.Contains(key);
        }

        /// <summary>
        /// Checks if the given key was lifted.
        /// This returns true only for a single frame.
        /// </summary>
        /// <param name="key">Key to check</param>
        /// <returns>True if the key was lifted, false otherwise</returns>
        public static bool IsKeyUp(Key key)
        {
            return keysUp.Contains(key);
        }

        /// <summary>
        /// Checks if the given key is held down.
        /// This returns true for each frame the key is held down.
        /// </summary>
        /// <param name="key">Key to check</param>
        /// <returns>True if the key is held down, false otherwise</returns>
        public static bool IsKeyPressed(Key key)
        {
            return keysPressed.Contains(key);
        }

        /// <summary>
        /// Checks if the given mouse button was pressed down.
        /// This returns true only for a single frame.
        /// </summary>
        /// <param name="btn">Button to check</param>
        /// <returns>True if the mouse button was pressed down, false otherwise</returns>
        public static bool IsMouseDown(MouseButton btn)
        {
            return mouseDown.Contains(btn);
        }

        /// <summary>
        /// Checks if the given mouse button was lifted.
        /// This returns true only for a single frame.
        /// </summary>
        /// <param name="btn">Button to check</param>
        /// <returns>True if the button was lifted, false otherwise</returns>
        public static bool IsMouseUp(MouseButton btn)
        {
            return mouseUp.Contains(btn);
        }

        /// <summary>
        /// Checks if the given mouse button is held down.
        /// This returns true for each frame the button is held down.
        /// </summary>
        /// <param name="btn">Button to check</param>
        /// <returns>True if the button is held down, false otherwise</returns>
        public static bool IsMousePressed(MouseButton btn)
        {
            return mousePressed.Contains(btn);
        }

        /// <summary>
        /// Checks if the mouse did move since the last frame
        /// </summary>
        /// <returns>True if mouse has moved, false otherwise</returns>
        public static bool HasMouseMoved()
        {
            return mouseMoved;
        }
    }
}
